#ifndef LIB_GEOUTILS_SHAPE_TOOL_H
#define LIB_GEOUTILS_SHAPE_TOOL_H

#include "libGeoutils/shape/CoordZ.h"
#include "libGeoutils/shape/Polyline.h"
#include "libGeoutils/shape/Rectangle.h"
#include "libGeoutils/shape/Segment.h"

namespace geo {
namespace tool {
class ShapeToolPrivate;
class GEOUTILS_EXPORT ShapeTool final
{
public:
	using sptr = std::shared_ptr<ShapeTool>;
	using csptr = std::shared_ptr<const ShapeTool>;

	ShapeTool();
	~ShapeTool();

	/*
	* Calculate Distance(km) Between Two coords
	* return unit: km
	*/
	bool calc_coord_distance(geo::shape::Coord::sptr coord1, geo::shape::Coord::sptr coord2, double& res) const;
	bool calc_coord_distance(geo::shape::Coord coord1, geo::shape::Coord coord2, double& res) const;
	bool calc_coord_distance(double lon1, double lat1, double lon2, double lat2, double& res) const;
	/*
	* Calculate Bearing Between Two coords
	* return unit: du
	*/
	bool calc_coord_bearing(geo::shape::Coord::sptr coord1, geo::shape::Coord::sptr coord2, double& res) const;
	bool calc_coord_bearing(geo::shape::Coord coord1, geo::shape::Coord coord2, double& res) const;
	bool calc_coord_bearing(double lon1, double lat1, double lon2, double lat2, double& res) const;
	/*
	* Calculate Destination From Target Coord To a Km's Distance
	* return: coord
	*/
	geo::shape::Coord calc_destination(geo::shape::Coord coord, double dist_km, double bearing_deg) const;
	/**
	 * @brief Calculates a series of points along a circle on the Earth's surface.
	 *
	 * This function computes 'num_points' coordinates that lie on a circle defined by a
	 * 'center' coordinate and a 'radius_km'. The points are generated starting from
	 * 'start_bearing_deg' (clockwise from North). It also updates the 'rect'
	 * parameter to encompass all calculated points.
	 *
	 * @param center The central coordinate of the circle.
	 * @param radius_km The radius of the circle in kilometers.
	 * @param start_bearing_deg The bearing in degrees (0-360) from North to start generating points.
	 * @param num_points The total number of points to calculate along the circle.
	 * @param rect A geo::shape::Rectangle object that will be updated to include all calculated points.
	 * @return A vector of pairs, where each pair contains a geo::shape::Coord representing
	 *         a point on the circle and a double (typically the distance to the center, or 0.0 if not needed).
	 */
	std::vector<std::pair<geo::shape::Coord, double>> calculate_circle_points(
		const geo::shape::Coord& center, 
		double radius_km, 
		double start_bearing_deg, 
		int num_points, 
		geo::shape::Rectangle& rect);

	std::string getLastErrorMessage() const;

protected:
	std::shared_ptr<ShapeToolPrivate> d;

private:

};

} //namespace tool
} // namespace geo

#endif // !LIB_GEOUTILS_SHAPE_TOOL_H
